/*
 * CWriter.h
 *
 *  Created on: 05.03.2012
 *      Author: caffeine
 */

#ifndef __IWRITER_H__
#define __IWRITER_H__
//#include <irrlicht.h>
#include <stdarg.h>
#include <stdio.h>
#include "../types.h"
#include "../IReferenceCounted.h"
#include <lampe/config.h>
 
namespace lampe{
namespace stream{


class IWriter:public virtual IReferenceCounted{
protected:
	template <class T>
void writeVariable(T res){
	write(&res,sizeof(T));
}
public:

	/**
	 * Записывает данные в буфер
	 *
	 * @param buffer указатель на данные, которые нужно записать
	 * @param size размер данных, которые нуно записать
	 *
	 * @return сколько байтов было записано в буфер
	 */
	virtual u32 write(void* buffer, u32 size) = 0;



	/**
	 * Записывает 1 символ размером 1 байт
	 *
	 *  @param res записываемый символ
	 */
	void writeC8(c8 res){
		writeVariable<c8>(res);
	}

	/**
	 * Записывает целое беззнаковое число
	 *
	 *  @param res число
	 */
	void writeU8(u8 res){
		writeVariable<u8>(res);
	}

	/**
	 * Записывает целое беззнаковое число
	 *
	 *  @param res число
	 */
	void writeU16(u16 res){
		writeVariable<u16>(res);
	}

	/**
	 * Записывает целое беззнаковое число
	 *
	 *  @param res число
	 */
	void writeU32(u32 res){
		writeVariable<u32>(res);
	}

	/**
	 * Записывает целое знаковое число
	 *
	 *  @param res число
	 */
	void writeS8(s8 res){
		writeVariable<s8>(res);
	}

	/**
	 * Записывает целое знаковое число
	 *
	 *  @param res число
	 */
	void writeS16(s16 res){
		writeVariable<s16>(res);
	}

	/**
	 * Записывает целое знаковое число
	 *
	 *  @param res число
	 */
	void writeS32(s32 res){
		writeVariable<s32>(res);
	}

	/**
	 * Записывает нецелое число
	 *
	 *  @param res число
	 */
	void writeF64(f64 res){
		writeVariable<f64>(res);
	}

	/**
	 * Записывает нецелое число
	 *
	 *  @param res число
	 */
	void writeF32(f32 res){
		writeVariable<f32>(res);
	}

	/**
	 * Записывает строку
	 *
	 *  @param res строка
	 */
	void writeStringc(String data){
		writeU32(data.size());
		writeText(data);
	}
#ifndef NOT_USING_IRRLICHT
	/**
	 * Записывает вектор, состоящий из трёх нецелых чисел
	 *
	 *  @param res вектор
	 */
	void writeVector3df(Vector3df res){
		writeF32(res.X);
		writeF32(res.Y);
		writeF32(res.Z);
	}

	
	/**
	 * Записывает выктор, состоящийх из двух нецелых чисел
	 *
	 *  @param res вектор
	 */
	void writeVector2df(Vector2df res){
		writeF32(res.X);
		writeF32(res.Y);
	}

	/**
	 * Записывает вектор, состоящийх из двух знаковых чисел
	 *
	 *  @param res вектор
	 */
	void writeVector2di(Vector2di res){
		writeS32(res.X);
		writeS32(res.Y);
	}

	/**
	 * Записывает записывает вектор, состоящий из трёх знаковых чисел
	 *
	 *  @param res вектор
	 */
	void writeVector3di(Vector3di res){
		writeS32(res.X);
		writeS32(res.Y);
		writeS32(res.Z);
	}
	#endif
	/**
	 * Записывает строку как данные в текст
	 * 
	 * @param data строка, которую нужно записать
	 */
	void writeText(String data,...){
		const char*fmt=data.c_str();
		va_list marker;
		va_start(marker, fmt);
#ifdef WINDOWS_PLATFORM
		size_t len = _vscprintf(fmt, marker) + 1;
#endif
#ifdef POSIX_LIBLARY
		char c;
		size_t len=vsnprintf(&c, 1, fmt, marker)+1;
#endif
		c8*buf=new c8[len+1];
		buf[len]=char(0);
		vsprintf(&buf[0],fmt,marker);
		write(&buf[0],len-1);
		delete[]buf;
	}
	
	void writeSText(String data){
		write((void*)&data.c_str()[0],data.length());
	}
	
	/**
	 * Записывает строку, добовляя в конец знак перевода строки, а затем знак конца строки
	 * 
	 * @param data строка, которую нужно записать
	 */
	void writeLine(String data){
		String d=data+"\r\n";
		write(&d[0],d.size());
	}

	virtual ~IWriter(){
	}

	/**
	 * Записывает содержание пакета данных
	 *
	 * @param packet пакет данных
	 */
	 /*
	void writePacket(IPacketReader*packet){
		packet->grab();
		writeU32(packet->size());
		char*buffer=new char[LAMPE_PACKET_BUFFER_SIZE];
		u32 size=0;
		while ((size=packet->read(&buffer[0],LAMPE_PACKET_BUFFER_SIZE))>0)
			write(buffer,size);
		delete[]buffer;
		packet->drop();
	}
	*/
};

}//namespace stream
}//namespace lampe
#endif /* IWRITER_H_ */
